/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TYPE_H
#define IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TYPE_H

#include <string>
#include <hilog/log.h>
#include <resourcemanager/ohresmgr.h>
namespace ImageKnifePro {

/**
 * @brief 加载请求类型
 */
enum class ImageRequestType {
    /**
     * @brief 加载主图
     */
    MAIN_SRC = 0,
    /**
     * @brief 加载占位图
     */
    PLACE_SRC,
    /**
     * @brief 加载错误图
     */
    ERROR_SRC
};

/**
 * @brief 图片文件格式枚举
 */
enum class ImageFormat {
    /**
     * @brief 未知图片格式
     */
    UNKNOWN = 0,
    /**
     * @brief jpg图片格式
     */
    JPG,
    /**
     * @brief png图片格式
     */
    PNG,
    /**
     * @brief webp图片格式
     */
    WEBP,
    /**
     * @brief bmp图片格式
     */
    BMP,
    /**
     * @brief gif图片格式
     */
    GIF,
    /**
     * @brief svg图片格式
     */
    SVG,
    /**
     * @brief tiff图片格式
     */
    TIFF,
    /**
     * @brief heic图片格式
     */
    HEIC,
    /**
     * @brief ico图片格式
     */
    ICO,
};

/**
 * @brief 图片源联合类型枚举
 */
enum DataType : unsigned int {
    /**
     * @brief 未定义类型，初始值
     */
    UNDEFINED = 1,
    /**
     * @brief 字符串
     */
    STRING = 1 << 1,
    /**
     * @brief 整数int类型
     */
    NUMBER = 1 << 2,
    /**
     * @brief pixelmap图片对象指针，原始类型为OH_PixelmapNative
     */
    PIXELMAP = 1 << 3,
    /**
     * @brief 本地资源，解析自ArkTs的Resource，依赖页面上下文。C API使用不支持
     */
    RESOURCE = 1 << 4,
};

/**
 * @brief 缓存策略枚举
 */
enum class CacheStrategy {
    /**
     * @brief 默认写入/读取内存和文件缓存
     */
    DEFAULT = 0,
    /**
     * @brief 只操作内存缓存
     */
    MEMORY = 1,
    /**
     * @brief 只操作文件缓存
     */
    FILE = 2,
    /**
     * @brief 不操作缓存
     */
    NONE = 3
};

/**
 * @brief 加载请求在队列中的优先级
 */
enum class Priority {
    /**
     * @brief 加载请求排入高优先级队列
     */
    HIGH = 0,
    /**
     * @brief 加载请求排入中优先级队列
     */
    MEDIUM,
    /**
     * @brief 加载请求排入低优先级队列
     */
    LOW
};

/**
 * @brief 内存/文件缓存拦截器的任务类型
 */
enum class CacheTaskType {
    /**
     * @brief 标明当前拦截器不属于内存、文件缓存责任链，不执行缓存任务
     */
    NONE = 0,
    /**
     * @brief 当前拦截器需要进行写缓存任务
     */
    WRITE,
    /**
     * @brief 当前拦截器需要进行读缓存任务
     */
    READ
};

/**
 * @brief 降采样策略
 */
enum class DownSamplingStrategy {
    /**
     * @brief 不进行降采样
     */
    NONE = 0,
    /**
     * @brief 默认值，仅在图片分辨率超过上限7680 X 4320时，宽高等比降为7680 X 4320
     */
    DEFAULT,
    /**
     * @brief 两边自适应内存优先
     */
    FIT_CENTER_MEMORY,
    /**
     * @brief 两边自适应质量优先
     */
    FIT_CENTER_QUALITY,
    /**
     * @brief 按照宽高比的最大比进行适配内存优先
     */
    CENTER_INSIDE_MEMORY,
    /**
     * @brief 按照宽高比的最大比进行适配质量优先
     */
    CENTER_INSIDE_QUALITY,
    /**
     * @brief 宽高进行等比缩放宽高里面最小的比例先放进去，然后再根据原图的缩放比去适配
     */
    AT_LEAST,
    /**
     * @brief 请求尺寸大于实际尺寸不进行放大
     */
    AT_MOST
};

/**
 * @brief 图片加载请求的错误码, 部分错误码来自默认实现的拦截器
 */
enum class LoadFailedCode {
    /**
     * @brief 未知错误
     */
    UNKNOWN_ERROR = 1,
    /**
     * @brief 请求在排队时被取消
     */
    QUEUE_CANCEL = 1000000,
    /**
     * @brief 请求在执行中被取消
     */
    LOADING_CANCEL = 1000001,
    /**
     * @brief 线程创建异常
     */
    DISPATCH_THREAD = 1000002,
    /**
     * @brief 生成key异常
     */
    GENERATE_KEY = 1000003,
    /**
     * @brief  图片加载失败
     */
    LOAD_IMAGE_FAILED = 100300,
    /**
     * @brief 本地资源加载失败
     */
    LOAD_LOCAL_FILE_FAILED = 100401,
    /**
     * @brief 创建ImageSource 失败
     */
    IMAGE_SOURCE_ERROR = 100501,
    /**
     * @brief 创建pixelmap失败，解码失败
     */
    IMAGE_PIXEL_MAP_ERROR = 100502,
    /**
     * @brief DECODE过程中失败，解码失败
     */
    IMAGE_DECODE_FAILED = 100503
};

/**
 * @brief 图片加载失败的错误信息
 */
struct ErrorInfo {
    /**
     * @brief 错误发生所在的图片加载阶段描述
     */
    std::string phase;
    /**
     * @brief 图片加载失败的错误码
     */
    LoadFailedCode code = LoadFailedCode::UNKNOWN_ERROR;
};

/**
 * @brief 图片解码后的信息
 */
struct DecodeImageInfo {
    /**
     * @brief 解码后的宽度
     */
    uint32_t contentWidth = 0;
    /**
     * @brief 解码后的高度
     */
    uint32_t contentHeight = 0;
};

/**
 * @brief 原始Image组件Oncomplete回调函数入参
 */
struct EventImage {
    /**
     * @brief 加载的状态，值为0代表图片加载成功，值为1代表图片解码成功
     */
    int32_t loadingStatus;
    /**
     * @brief 图片宽度，单位px
     */
    float width;
    /**
     * @brief 图片高度，单位px
     */
    float height;
    /**
     * @brief 组件宽度，单位px
     */
    float componentWidth;
    /**
     * @brief 组件高度，单位px
     */
    float componentHeight;
    /**
     * @brief 图片绘制区域相对组件X轴位置，单位px
     */
    float contentOffsetX;
    /**
     * @brief 图片绘制区域相对组件Y轴位置，单位px
     */
    float contentOffsetY;
    /**
     * @brief 图片绘制区域宽度，单位px
     */
    float contentWidth;
    /**
     * @brief 图片绘制区域高度，单位px
     */
    float contentHeight;
};

/**
 * @brief 图片加载的时间戳信息
 */
struct TimeInfo {
    /**
     * @brief 请求创建完成，开始处理的时间
     */
    uint64_t executeTime = 0;
    /**
     * @brief 请求开始加载的时间
     * requestStartTime - executeTime 等于队列排队等其它耗时时间
     */
    uint64_t requestStartTime = 0;
    /**
     * @brief 请求结束时间
     */
    uint64_t requestEndTime = 0;
    /**
     * @brief 请求取消时间
     */
    uint64_t requestCancelTime = 0;
    /**
     * @brief 内存缓存责任链读缓存任务开始时间
     */
    uint64_t memoryCheckStartTime = 0;
    /**
     * @brief 内存缓存责任链读缓存任务结束时间
     * 没有内存缓存则结束时间为0
     */
    uint64_t memoryCheckEndTime = 0;
    /**
     * @brief 文件缓存责任链读缓存任务开始时间
     */
    uint64_t diskCheckStartTime = 0;
    /**
     * @brief 文件缓存责任链读缓存任务结束时间
     * 没有文件缓存则结束时间为0
     */
    uint64_t diskCheckEndTime = 0;
    /**
     * @brief 图片加载责任链开始时间
     */
    uint64_t loadImageStartTime = 0;
    /**
     * @brief 图片加载责任链结束时间
     */
    uint64_t loadImageEndTime = 0;
    /**
     * @brief 图片解码责任链开始时间
     */
    uint64_t decodeStartTime = 0;
    /**
     * @brief 图片解码责任链结束时间
     */
    uint64_t decodeEndTime = 0;
};

/**
 * @brief 自动采集的请求数据采集的相关图片信息，仅采集主图信息
 */
struct ImageInfo {
    /**
     * @brief 图片加载请求的ID标识
     */
    std::string requestId;
    /**
     * @brief 图片原始宽度
     */
    uint32_t imageWidth = 0;
    /**
     * @brief 图片原始高度
     */
    uint32_t imageHeight = 0;
    /**
     * @brief 图片字节数
     */
    uint32_t bufSize = 0;
    /**
     * @brief 网络下载http状态码，0为没有进行网络下载
     */
    uint32_t httpCode = 0;
    /**
     * @brief 图片加载的时间信息
     */
    TimeInfo timeInfo;
    /**
     * @brief 图片加载失败时的错误信息。如果图片加载成功，该信息为空且错误码为默认值
     */
    ErrorInfo errorInfo;
    /**
     * @brief 图片的文件格式类型：png，jpg，gif等
     */
    ImageFormat type = ImageFormat::UNKNOWN;
    /**
     * @brief 动图的帧数，静态图片帧数为1
     */
    uint32_t frameCount = 0;
    /**
     * @brief 图片解码后的信息，包含每帧图片解码后的宽高
     */
    std::vector<DecodeImageInfo> decodeImages;
    /**
     * @brief 用户自定义数据, 在ImageKnifeOption.customData中进行设置
     * 图片加载开始时，ImageKnifeOption.customData的指针地址会赋值给这个成员，以便在加载回调中进行访问
     * 析构通过设置ImageKnifeOption.finalize进行
     * 该自定义数据不会传递给ArkTs的ImageInfo接口，没有对应的成员
     */
    void *customData = nullptr;
};

/**
 * @brief 图片加载回调，只对主图加载生效
 */
struct OnLoadCallBack {
    /**
     * @brief 加载开始回调
     */
    std::function<void(ImageInfo imageInfo)> onLoadStart = nullptr;
    /**
     * @brief 加载成功回调
     */
    std::function<void(ImageInfo imageInfo)> onLoadSuccess = nullptr;
    /**
     * @brief 加载失败回调
     */
    std::function<void(std::string error, ImageInfo imageInfo)> onLoadFailed = nullptr;
    /**
     * @brief 加载取消回调
     */
    std::function<void(std::string reason, ImageInfo imageInfo)> onLoadCancel = nullptr;
    virtual ~OnLoadCallBack() = default;
};

/**
 * @brief 解析自ArkTs的Resource本地资源，依赖页面上下文。使用C API时无效
 */
struct Resource {
    /**
     * @brief 包名称
     */
    std::string bundleName;
    /**
     * @brief 模块名称
     */
    std::string moduleName;
    /**
     * @brief 资源id
     */
    int id;
    /**
     * @brief 第0个string类型资源参数
     */
    std::string param;
};

/**
 * @brief 解析自ArkTs的页面上下文Context，只能由ArkTs层传入。使用C API时无效
 */
struct Context {
    /**
     * @brief 解析自ArkTs侧Context.config
     * 包含深色模式，屏幕方向，设备类型等信息
     */
    ResourceManager_Configuration *config = nullptr;
    /**
     * @brief 本地资源管理器，用于读取本地文件
     */
    NativeResourceManager *resourceManager = nullptr;
};
}

/**
 * @brief 日志输出回调函数类型
 * @param logLevel 日志级别
 * @param function 输出日志时所在的文件函数信息。其值为nullptr表示当前日志不含有该信息。
 * @param line 输出日志时所在的行号, 部分日志该信息为0，即没有该信息
 * @param formatString 格式化字符串，使用OH_LOG_Print的格式，是printf的扩展
 * 在‘%’和具体的格式之间可以添加‘{public}’或‘{private}’
 * 例如: "%{public}d", "%{public}s"
 */
typedef void (*LogPrinter)(LogLevel logLevel, const char *function, int line, const char *formatString, ...);

#endif // IMAGE_KNIFE_C_KEKE_IMAGEKNIFE_TYPE_H
